home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Dev / SmallTalk / OrderedCollection.st < prev    next >
Text File  |  1995-08-25  |  8KB  |  265 lines

  1. "======================================================================
  2. |
  3. |   OrderedCollection Method Definitions
  4. |
  5.  ======================================================================"
  6.  
  7.  
  8. "======================================================================
  9. |
  10. | Copyright (C) 1990, 1991, 1992 Free Software Foundation, Inc.
  11. | Written by Steve Byrne.
  12. |
  13. | This file is part of GNU Smalltalk.
  14. |
  15. | GNU Smalltalk is free software; you can redistribute it and/or modify it
  16. | under the terms of the GNU General Public License as published by the Free
  17. | Software Foundation; either version 1, or (at your option) any later version.
  18. | GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
  19. | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  20. | FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  21. | details.
  22. | You should have received a copy of the GNU General Public License along with
  23. | GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
  24. | Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
  25. |
  26.  ======================================================================"
  27.  
  28.  
  29. "
  30. |     Change Log
  31. | ============================================================================
  32. | Author       Date       Change 
  33. | sbyrne     19 Sep 89      Converted to use real method categories.
  34. |
  35. | sbyrne     25 Apr 89      created.
  36. |
  37. "
  38.  
  39. SequenceableCollection variableSubclass: #OrderedCollection
  40.                instanceVariableNames: 'firstIndex lastIndex'
  41.                classVariableNames: ''
  42.                poolDictionaries: ''
  43.                category: nil
  44. !
  45.  
  46. OrderedCollection comment: 
  47. 'My instances represent ordered collections of arbitrary typed objects which
  48. are not directly accessible by an index.  They can be accessed indirectly
  49. through an index, and can be manipulated by adding to the end or based
  50. on content (such as add:after:)' !
  51.  
  52. !OrderedCollection class methodsFor: 'instance creation'!
  53.  
  54. new: anInteger
  55.     ^(super new: anInteger) initIndices
  56. !
  57.  
  58. new
  59.     ^self new: 16
  60.  
  61. ! !
  62.  
  63.  
  64.  
  65. !OrderedCollection methodsFor: 'accessing'!
  66. at: index
  67.     index _ index + firstIndex - 1.
  68.     (index >= firstIndex and: [ index <= lastIndex ])
  69.         ifTrue: [ ^self basicAt: index ]
  70.     ifFalse: [ self error: 'index out of bounds for ordered collection' ]
  71. !
  72.  
  73. at: index put: anObject
  74.     index _ index + firstIndex - 1.
  75.     (index >= firstIndex and: [ index <= lastIndex ])
  76.         ifTrue: [ ^self basicAt: index put: anObject ]
  77.     ifFalse: [ self error: 'index out of bounds for ordered collection' ]
  78. !    
  79.  
  80. after: oldObject
  81.     "Return the element after oldObject.  Error if oldObject not found or
  82.     if no following object is available"
  83.     firstIndex to: lastIndex do:
  84.         [ :index |        "should we use '=' or '==' here?"
  85.         (self basicAt: index) = oldObject
  86.             ifTrue: [
  87.             index < lastIndex
  88.                 ifTrue: [ ^self basicAt: index + 1 ]
  89.             ifFalse: [ ^self error: 'no following object' ] ]
  90.         ].
  91.     self error: 'object not found'
  92. !
  93.  
  94. before: oldObject
  95.     "Return the element after oldObject.  Error if oldObject not found or
  96.     if no following object is available"
  97.     firstIndex to: lastIndex do:
  98.         [ :index |        "should we use '=' or '==' here?"
  99.         (self basicAt: index) = oldObject
  100.             ifTrue: [
  101.             index > firstIndex
  102.                 ifTrue: [ ^self basicAt: index - 1 ]
  103.             ifFalse: [ ^self error: 'no preceding object' ] ]
  104.         ].
  105.     self error: 'object not found'
  106. !
  107.  
  108. copyEmpty
  109.     ^self species new: self basicSize
  110. !
  111.  
  112. size
  113.     ^lastIndex - firstIndex + 1
  114. ! !
  115.  
  116.  
  117.  
  118. !OrderedCollection methodsFor: 'adding'!
  119.  
  120. add: anObject
  121.     ^self addLast: anObject
  122. !
  123.  
  124. add: newObject after: oldObject
  125.     firstIndex to: lastIndex do:
  126.         [ :i | (self basicAt: i) = oldObject
  127.                 ifTrue: [ self at: i + 1 insertObject: newObject.
  128.                               ^newObject ] ].
  129.     self error: 'object not found in collection'
  130. !
  131.  
  132. add: newObject before: oldObject
  133.     firstIndex to: lastIndex do:
  134.         [ :i | (self basicAt: i) = oldObject
  135.                 ifTrue: [ self at: i - 1 insertObject: newObject.
  136.                               ^newObject ] ].
  137.     self error: 'object not found in collection'
  138. !
  139.  
  140.  
  141. addAllFirst: anOrderedCollection
  142.     anOrderedCollection reverseDo:
  143.         [ :element | self addFirst: element ].
  144.     ^anOrderedCollection
  145. !
  146.     
  147. addAllLast: anOrderedCollection
  148.     anOrderedCollection do:
  149.         [ :element | self addLast: element ].
  150.     ^anOrderedCollection
  151. !
  152.     
  153.  
  154. addFirst: newObject
  155.     firstIndex = 1
  156.         ifTrue: [ self growFirst ].
  157.     firstIndex _ firstIndex - 1.
  158.     ^self basicAt: firstIndex put: newObject
  159. !
  160.     
  161. addLast: newObject
  162.     lastIndex = self basicSize
  163.         ifTrue: [ self growLast ].
  164.     lastIndex _ lastIndex + 1.
  165.     ^self basicAt: lastIndex put: newObject
  166. ! !
  167.  
  168.  
  169.  
  170. !OrderedCollection methodsFor: 'removing'!
  171. removeFirst
  172.     lastIndex < firstIndex
  173.         ifTrue: 
  174.             [ ^self error: 'attempted to remove from an empty collection' ].
  175.     firstIndex _ firstIndex + 1.
  176.     ^self basicAt: firstIndex - 1
  177. !
  178.  
  179. removeLast
  180.     lastIndex < firstIndex
  181.         ifTrue: 
  182.             [ ^self error: 'attempted to remove from an empty collection' ].
  183.     lastIndex _ lastIndex - 1.
  184.     ^self basicAt: lastIndex + 1
  185. ! !
  186.  
  187.  
  188.  
  189. !OrderedCollection methodsFor: 'private methods'!
  190.  
  191. initIndices
  192.     firstIndex _ self basicSize // 2 max: 1.
  193.     lastIndex _ firstIndex - 1
  194. !
  195.  
  196. firstIndex: first lastIndex: last
  197.     firstIndex _ first.
  198.     lastIndex _ last
  199. !
  200.  
  201. growFirst
  202.     "Make growSize room at the start of the ordered collection, and copy
  203.     all the elements of the old collection into the new one starting
  204.     at the value that growSize returned."
  205.     | newOrderedCollection delta |
  206.     delta _ self growSize.
  207.     newOrderedCollection _ self growTo: self basicSize + delta.
  208.     firstIndex to: lastIndex do:
  209.         [ :index | newOrderedCollection basicAt: delta + index - 1
  210.                                     put: (self basicAt: index) ].
  211.     newOrderedCollection firstIndex: delta + firstIndex - 1
  212.                          lastIndex: delta + lastIndex - 1.
  213.     ^self become: newOrderedCollection    
  214. !
  215.  
  216. growLast
  217.     "Make growSize room at the end of the ordered collection, and copy
  218.     all the elements of the old collection into the new one starting
  219.     at firstIndex."
  220.     | newOrderedCollection |
  221.     newOrderedCollection _ self growTo: self basicSize + self growSize.
  222.     firstIndex to: lastIndex do:
  223.         [ :index | newOrderedCollection basicAt: index
  224.                                     put: (self basicAt: index) ].
  225.     newOrderedCollection firstIndex: firstIndex
  226.                          lastIndex: lastIndex.
  227.     ^self become: newOrderedCollection    
  228. !
  229.  
  230. grow
  231.     "Make growSize room in the collection, putting the old contents in the
  232.     middle."
  233.     | oldSize newSize newFirstIndex newOrderedCollection |
  234.     oldSize _ self basicSize.
  235.     newSize _ oldSize + self growSize.
  236.     newOrderedCollection _ self growTo: newSize.
  237.     newFirstIndex _ newSize - oldSize // 2 max: 1.
  238.     1 to: self size do:
  239.         [ :i | newOrderedCollection basicAt: i + newFirstIndex - 1
  240.                                 put: (self basicAt: i + firstIndex - 1) ].
  241.     newOrderedCollection firstIndex: newFirstIndex
  242.                          lastIndex: newFirstIndex + self size - 1.
  243.     ^self become: newOrderedCollection
  244. !
  245.  
  246. growTo: anInteger
  247.     ^self species new: anInteger
  248. !    
  249.  
  250. growSize
  251.     ^10                "number out of a hat"
  252. !
  253.  
  254. at: index insertObject: anObject
  255.     lastIndex = self basicSize ifTrue: [ self growLast ].
  256.     lastIndex to: index by: -1 do:
  257.         [ :i | self basicAt: i + 1
  258.                 put: (self basicAt: i) ].
  259.     self basicAt: index put: anObject.
  260.     ^anObject
  261. ! !
  262.  
  263.